#!/usr/bin/env python
# coding=UTF-8
import logging
import time
import datetime
from hashlib import md5
import urllib, urllib2
import random, json

# import requests
import cherrypy
import redis
from nsq.http import nsqd

import config
import dao
import util


def nsq_pub(topic, message):
    try:
        nsq_client = nsqd.Client("http://%s/" % config.NSQ_HTTP)
        if isinstance(message, dict):
            message = json.dumps(message, separators=(',', ':'))
        logging.info(u"推送消息:%s" % message)
        nsq_client.pub(topic, message)
        return True
    except:
        logging.error("nsq send error", exc_info=True)
        return False

pool = redis.ConnectionPool(host=config.REDIS_HOST, port=config.REDIS_PORT, db=config.REDIS_DB)
_r = redis.Redis(connection_pool=pool)

def get_client_ip():
    header = cherrypy.request.headers
    ip = ''
    ipList = header.get("X-Forwarded-For", "").replace(" ", "").split(",")
    if ipList:
        ip = ipList[0]
        if len(ipList) > 1 and ip[:3] in ('10.', '127', '192', '172'):
            ip = ipList[1]
    if not ip:
        ip = header.get('X-Real-Ip')
    if not ip:
        ip = header.get('Remote-Addr')
    if not ip:
        ip = header.get('REMOTE-ADDR')
    return ip

def get_phone_model(ua=''):
    #根据ua获取用户手机型号
    if not ua:
        header = cherrypy.request.headers
        ua = header.get("User-Agent", "")
    if "Android" in ua:
        info = ua.split(";")[-1].strip()
        if "MIUI" in info:
            sep = "MIUI"
        else:
            sep = "Build" 
        return info.split(sep)[0].strip()
    elif "iPhone" in ua:
        return "iPhone"
    return ""

def get_wx_user(access_token, openid):
    try:
        url = "http://api.weixin.qq.com/sns/userinfo?access_token=%s&openid=%s&lang=zh_CN" % (access_token, openid)
        # h = requests.get(url, verify=False)
        # res = h.json()
        logging.info(url)
        h = urllib2.urlopen(url)
        res = h.read()
        logging.info(res)
        res = json.loads(res)
        return res
    except:
        logging.error("wx api error", exc_info=True)
        return {}

def get_ip_data(ip):
    try:
        url = "http://int.dpool.sina.com.cn/iplookup/iplookup.php?format=json&ip=%s" % ip
        logging.info(url)
        h = urllib2.urlopen(url)
        res = h.read()
        logging.info(res)
        res = json.loads(res)
        return res
    except:
        logging.error("ip error", exc_info=True)
        return {}

def get_gps_data(lat, lon):
    try:
        url = "http://api.map.baidu.com/geocoder/v2/?ak=881ee671d059ace959431fbe7afbde2a&callback=&location=%s,%s&output=json&pois=1" % (lat, lon)
        logging.info(url)
        h = urllib2.urlopen(url)
        res = h.read()
        logging.info(res)
        res = json.loads(res)
        return res.get("addressComponent", {})
    except:
        logging.error("ip error", exc_info=True)
        return {}


def conf(cp, cv, bid, uid):
    conf_info = {}
    update_info = {}
    db = dao.Game_DB()
    conf_list = db.get_conf(bid)
    if conf_list:
        for conf in conf_list:
            conf_info[conf['param']] = conf['value']
    if cp == 'ios' and cv == conf_info.get('ios_version'):
        wx_login = 'n'
        guest_login = 'y'
    else:
        wx_login = 'y'
        guest_login = 'y'
    update_info['new_cv'] = '2.0.0'
    update_info['url'] = 'http://m.99ok.com.cn'
    update_info['tips'] = '新版更新提示说明新版更新提示说明新版更新提示说明新版更新提示说明新版更新提示说明新版更新提示说明'
    update_info['force_update'] = 'n'
    game_rule = []
    return {"code":0, "msg":"ok", "data":{"conf_info":conf_info, "update_info":update_info, "wx_login":wx_login, "guest_login":guest_login, "game_rule":game_rule}}
    
def login(cp, cv, bid, access_token, openid, devid, login_type):
    db = dao.Game_DB()
    if login_type == 'wx':
        devid = ''
        if not openid:
            return {"code":1000, "msg":"openid not null"}
        user_info = db.get_wx_user(bid, openid)
        if user_info:
            uid = user_info['uid']
            if access_token:
                wx_user_info = get_wx_user(access_token, openid)
                if wx_user_info.get("openid"):
                    head = wx_user_info['headimgurl']
                    name = wx_user_info['nickname'].replace("'"," ")
                    sex = wx_user_info['sex']
                    if head != user_info['head'] or name != user_info['name'] or sex != user_info['sex']:
                        db.update_user(bid, uid, head, name, sex) 
    else:
        user_info = db.get_dev_user(bid, devid)
    tcp_server = db.get_connserver()
    if not tcp_server:
        tcp_server = {"ip":"47.93.90.95", "port":8098}
    ip = get_client_ip()
    if user_info:
        user_info.pop("ctime")
        user_info['pwd'] = user_info['md5pwd']
        user_info.pop("md5pwd")
        get_joined_room = db.get_joined_room(bid, user_info['uid'])
        if get_joined_room:
            joined_room = get_joined_room['rid']
        else:
            joined_room = 0
        user_info['ip'] = ip
        user_info['online'] = 'n'
        key = "%s_%s" % (bid, str(user_info['uid']))
        _r.hmset(key, user_info)
        return {"code":0, "msg":"登录成功",
                "data":{"user_info":user_info,
                        "joined_room":joined_room,
                        "tcp_server":tcp_server,
                        }
                }

    max_uid = db.get_max_uid(bid)
    if not (max_uid and max_uid['uid']):
        uid = 100001
    else:
        uid = long(max_uid['uid']) + 1
        
    if login_type == 'wx':
        wx_user_info = get_wx_user(access_token, openid)
        if not wx_user_info or not wx_user_info.get("openid"):
            return {"code":1001, "msg":"登录失败,获取微信信息异常"}
        head = wx_user_info['headimgurl']
        name = wx_user_info['nickname'].replace("'"," ")
        sex = wx_user_info['sex']
    else:
        #head = ""
        head = "%s/voice/head/%s.png" % (config.UPLOAD_ADDR, uid % 8 + 1)
        phone_model = get_phone_model()
        if phone_model:
            name = phone_model
        else:
            name = u"游客"
        sex = 1
        openid = ""
    card = 2
    pwd = str(random.randint(100000, 999999))
    pid = 0
    mcard = 1
    i = db.add_user(bid, uid, pwd, openid, head, name, sex, cp, cv, card, pid, devid, mcard)
    if i != 1:
        db.res = False
        return {"code":1002, "msg":"注册账户异常"}
    user_info = {"uid":uid, "pwd":md5(pwd).hexdigest(), "head":head, "name":name, "sex":sex, "ip":ip, "card":card}
    key = "%s_%s" % (bid, str(uid))
    _r.hmset(key, user_info)
    return {"code":0, "msg":"登录成功",
            "data":{"user_info":user_info,
                    "joined_room":0,
                    "tcp_server":tcp_server,
                    }
            }

def get_user_info(bid, uid):
    db = dao.Game_DB()
    data = db.user_info(bid, uid)
    del data['ctime']
    del data['pwd']
    del data['md5pwd']
    user_stat = db.query_user_stat(bid, uid)
    if user_stat:
        for stat in user_stat:
            all_round = stat['all_round']
            win_round = stat['win_round']
            game_type = stat['game_type']
            stat['game_name'] = config.GAME_TYPE_NAME.get(game_type, game_type)
            if all_round:
                stat['win_rate'] = "%s%%" % (win_round * 100/ all_round)
            else:
                stat['win_rate'] = "0%"
    else:
        user_stat = [{"game_name":"广东推倒胡", "win_rate":"0%","all_round":0, "win_round":0, "score":0},{"game_name":"转转麻将", "win_rate":"0%","all_round":0, "win_round":0, "score":0},]
    data['user_stat'] = user_stat
    return {"code":0, "msg":"ok", "data":data}

def set_pid(bid, uid, pid):
    db = dao.Game_DB()
    data = db.user_info(bid, uid)
    if data['pid']:
        return {"code":2101, "msg":"该账户已存在推荐人,不能修改", "data":{}}
    if not db.user_info(bid, pid):
        return {"code":2102, "msg":"推荐人ID不存在", "data":{}}
    db.set_pid(bid, uid, pid)
    return {"code":0, "msg":"操作成功", "data":{}}

def set_signature(bid, uid, signature):
    db = dao.Game_DB()
    db.set_signature(bid, uid, signature)
    return {"code":0, "msg":"操作成功", "data":{}}

def bf_create_club(cp, cv, bid, uid, pwd, lat, lon):
    db = dao.Game_DB()
    user_info = db.user_info(bid, uid)
    if user_info['card'] < 1:
        return {"code":1101, "msg":"您的账户房卡不足"}
    created_club = 0
    rows = db.myclub(bid, uid)
    if rows:
        created_club = len(rows)
        if created_club >= 10:
            return {"code":2201, "msg":"您已创建了10个俱乐部达到了上限"}
    province = ""
    city = ""
    lat, lon = "", ""
    if lat and lon:
        location = get_gps_data(lat, lon)
    else:
        ip = get_client_ip()
        location = get_ip_data(ip)
    if location:
        province = location.get("province", "").replace(u"省", "")
        city = location.get("city", "").replace(u"市", "")
    tag = [u"不加陌生人", u"只加女人"]
    return {"code":0, "msg":"ok", "data":{"max_club":10, "created_club":created_club, "province":province, "city":city, "tag":tag}}

def create_club(cp, cv, bid, uid, pwd, name, province, city, head, tag, des):
    if not name:
        return {"code":2301, "msg":"请输入俱乐部名称"}
    db = dao.Game_DB()
    user_info = db.user_info(bid, uid)
    if user_info['card'] < 1:
        return {"code":2302, "msg":"您的账户房卡不足"}
    rows = db.myclub(bid, uid)
    if rows:
        created_club = len(rows)
        if created_club >= 10:
            return {"code":2304, "msg":"您已创建了10个俱乐部达到了上限"}
    try:
        #(i, cid) = db.add_club(bid, name.decode("utf-8"), uid, head, province.decode("utf-8"), city.decode("utf-8"), des.decode("utf-8"), tag.decode("utf-8"), 80)
        (i, cid) = db.add_club(bid, name, uid, head, province, city, des, tag, 80)
        db.join_club(uid, cid, 2, 1)
        return {"code":0, "msg":"ok", "data":{"cid":cid}}
    except:
        db.res = False
        logging.error("create room error:", exc_info=True)
        return {"code":2305, "msg":"创建失败"}

def myclub(bid, uid):
    db = dao.Game_DB()
    mine_club = db.myclub(bid, uid)
    for club in mine_club:
        cid = club['cid']
        #club_len = db.get_club_member_len(cid)
        #club['join_user'] = club_len['number']
        #club['online_user'] = club_len['online_user']
        club['share_title'] = u"俱乐部:%s,【俱乐部ID:%s】 " % (club['name'], cid)
        club['share_des'] = club['des']
        club['share_url'] = "%s/index/club?cid=%s" % (config.WAP, cid)
        tag = club['tag']
        if tag:
            tag = tag.split(",")
            club['tag'] = "#"+"    #".join(tag)
    return {"code":0, "msg":"ok", "data":{"mine_club":mine_club}}

def joined_club(bid, uid):
    db = dao.Game_DB()
    mine_club = db.joined_club(bid, uid)
    for club in mine_club:
        cid = club['cid']
        club['share_title'] = u"俱乐部:%s,【俱乐部ID:%s】 " % (club['name'], cid)
        club['share_des'] = club['des']
        club['share_url'] = "%s/index/club?cid=%s" % (config.WAP, cid)
        tag = club['tag']
        if tag:
            tag = tag.split(",")
            club['tag'] = "#"+"    #".join(tag)
    return {"code":0, "msg":"ok", "data":{"joined_club":mine_club}}

def find_club(bid, uid, cid='', tag='', city=''):
    db = dao.Game_DB()
    if cid:
        if not cid.isdigit():
            #return {"code":0, "msg":"请输入数字的俱乐部ID", "data":{}}
            clubs = db.query_club_by_city(bid, uid, cid, 20)
            if not clubs:
                clubs = db.query_club_by_name(bid, uid, cid, 20)
        else:
            club = db.get_club(cid)
            if not club:
                clubs = []
            else:
                clubs = [club]
    elif tag:
        clubs = db.query_club_by_tag(tag)
    elif city:
        clubs = db.query_club_by_city(bid, uid, city, 20)
    else:
        clubs = []
    for club in clubs:
        club_len = db.get_club_member_len(club['cid'])
        club['join_user'] = club_len['number']
        tag = club['tag']
        if tag:
            tag = tag.split(",")
            club['tag'] = "#"+"    #".join(tag)
        in_club = db.in_club(club['cid'], uid)
        if in_club:
            club['joined_flag'] = 'y'
            club['verify'] = in_club['verify']
        else:
            club['joined_flag'] = 'n'
            club['verify'] = 0
    if not clubs:
        code = 400
        msg = u"没有找到结果"
    else:
        code = 0
        msg = ""
    return {"code":code, "msg":msg, "data":{"clubs":clubs}}

def recommend_club(bid, uid):
    local_club = []
    db = dao.Game_DB()
    ip = get_client_ip()
    location = get_ip_data(ip)
    city = location.get("city")
    if city:
        local_club = db.query_club_by_city(bid, uid, city, 20)
        for club in local_club:
            #club_len = db.get_club_member_len(club['cid'])
            #club['join_user'] = club_len['number']
            in_club = db.in_club(club['cid'], uid)
            if in_club:
                club['joined_flag'] = 'y'
                club['verify'] = in_club['verify']
            else:
                club['joined_flag'] = 'n'
                club['verify'] = 0
            tag = club['tag']
            if tag:
                tag = tag.split(",")
                club['tag'] = "#"+"    #".join(tag)
    hot_club = db.query_hot_club(bid, uid)
    for club in hot_club:
        in_club = db.in_club(club['cid'], uid)
        if in_club:
            club['joined_flag'] = 'y'
            club['verify'] = in_club['verify']
        else:
            club['joined_flag'] = 'n'
            club['verify'] = 0
        tag = club['tag']
        if tag:
            tag = tag.split(",")
            club['tag'] = "#"+"    #".join(tag)
        #club_len = db.get_club_member_len(club['cid'])
        #club['join_user'] = club_len['number']
    return {"code":0, "msg":"", "data":{"hot_club":hot_club, "local_club":local_club, "city":city}}

def join_club(bid, uid, cid):
    db = dao.Game_DB()
    club_info = db.get_club(cid)
    if not club_info:
        return {"code":2401, "msg":"俱乐部不存在", "data":{}}
    elif club_info['flag'] != 'y':
        return {"code":2402, "msg":"俱乐部已解散", "data":{}}
    if db.in_club(cid, uid):
        return {"code":0, "msg":"", "data":{"club_info":club_info}}
    i = db.join_club(uid, cid, 0, 0)
    if i == 0:
        return {"code":2403, "msg":"已经在俱乐部当中", "data":{}}
    db.update_join_user(bid, cid, 1)
    return {"code":0, "msg":"加入申请已提交,请等待审核", "data":{"club_info":club_info}} 

def unverify_member(bid, cid, uid):
    db = dao.Game_DB()
    myrole = db.get_myrole(cid, uid)
    if not myrole or myrole['role'] < 1:
        apply_user = []
    else:
        apply_user = db.unverify_member(bid, cid)
    return {"code":0, "msg":"ok", "data":{"apply_user":apply_user}}

def join_verify(cid, bid, uid, member, verify):
    db = dao.Game_DB()
    myrole = db.get_myrole(cid, uid)
    if not myrole or myrole['role'] < 1:
        return {"code":2501, "msg":"你不是管理员不能审核用户", "data":{}}
    if str(verify) == '0':
        db.quit_club(cid, member)
        db.update_join_user(bid, cid, -1)
    else:
        db.verify_club_member(cid, member, verify)
    return {"code":0, "msg":"操作成功", "data":{}}

def club_member(cid, bid, uid, member, act):
    #act:list/del/set_manager/unset_manager
    db = dao.Game_DB()
    myrole = db.get_myrole(cid, uid)
    if not myrole:
        return {"code":2511, "msg":"你不是俱乐部成员", "data":{}}
    role = myrole['role']
    if act == 'set_manager':
        if role != 2:
            return {"code":2512, "msg":"你不是创建者不能进行操作", "data":{}}
        db.set_club_member(cid, member, 1, 1)
    elif act == 'unset_manager':
        if role != 2:
            return {"code":2513, "msg":"你不是创建者不能进行操作", "data":{}}
        db.set_club_member(cid, member, 0, 2)
    elif act == 'del':
        if role < 1:
            return {"code":2514, "msg":"你不是管理员,不能剔除用户", "data":{}}
        db.quit_club(cid, member)
    rows = db.club_member(bid, cid)
    return {"code":0, "msg":"操作成功", "data":{"club_member":rows}}

def club_set(cid, name, head, des, bg_pic, tag):
    db = dao.Game_DB()
    club = db.get_club(cid)
    if not club:
        return {"code":2521, "msg":"俱乐部不存在", "data":{}}
    if name:
        db.update_club_col(cid, "name", name)
    if head:
        db.update_club_col(cid, "head", head)
    if des:
        db.update_club_col(cid, "des", des)
    if bg_pic:
        db.update_club_col(cid, "bg_pic", bg_pic)
    if tag:
        tag = tag.replace(" ",",")
        db.update_club_col(cid, "tag", tag)
    db.commit()
    club = db.get_club(cid)
    return {"code":0, "msg":"操作成功", "data":{"club":club}}

def club_info(bid, cid, uid):
    started_game = []
    nostart_game = []
    db = dao.Game_DB()
    club = db.get_club(cid)
    if not club:
        club = {}
    else:
        myrole = db.get_myrole(cid, uid)
        if myrole:
            club['verify'] = myrole['verify']
            club['role'] = myrole['role']
        else:
            club['verify'] = 0
            club['role'] = 0
        club_len = db.get_club_member_len(cid)
        club['join_user'] = club_len['number']
        club['online_user'] = club_len['online_user']
        
        club['share_title'] = u"俱乐部:%s,【俱乐部ID:%s】 " % (club['name'], cid)
        club['share_des'] = club['des']
        club['share_url'] = "%s/index/club?cid=%s" % (config.WAP, cid)
        tag = club['tag']
        if tag:
            tag = tag.split(",")
            club['tag'] = " ".join(tag)
        joined_game = db.get_joined_game(uid)
        if joined_game:
            joined_gid = joined_game['gid']
        else:
            joined_gid = 0
            
        #获取当前俱乐部的招募中和进行中的牌局
        started_game = db.club_games(cid, 1)
        for game in started_game:
            gid = game['gid']
            game_member = db.get_game_count(gid)
            game['join_player'] = game_member['c']
            game['share_title'] = u"俱乐部:%s,【俱乐部ID:%s】牌局【%s】" % (club['name'], cid, game['name'])
            game['share_des'] = game['game_des']
            game['share_url'] = "%s/index/club?gid=%s" % (config.WAP, gid)
            game_type = game['game_type']
            game['game_type_name'] = config.GAME_TYPE_NAME.get(game_type, game_type)
        nostart_game = db.club_games(cid, 0)
        for game in nostart_game:
            gid = game['gid']
            game_member = db.get_game_count(gid)
            game['join_player'] = game_member['c']
            game['share_title'] = u"俱乐部:%s,【俱乐部ID:%s】牌局【%s】" % (club['name'], cid, game['name'])
            game['share_des'] = game['game_des']
            game['share_url'] = "%s/index/club?gid=%s" % (config.WAP, gid)
            if gid == joined_gid:
                game['joined_flag'] = 'y'
            else:
                game['joined_flag'] = 'n'
            game_type = game['game_type']
            game['game_type_name'] = config.GAME_TYPE_NAME.get(game_type, game_type)
        db.update_club_online(cid, uid, 'y')
        
    return {"code":0, "msg":"ok", "data":{"club":club, "nostart_game":nostart_game, "started_game":started_game, "joined_game":joined_gid}}

def create_game(cid, name, game_type, player, all_round, all_player, rule):
    if not name:
        return {"code":2600, "msg":"请输入牌局名称", "data":{}}
    all_player = int(all_player)
    player = int(player)
    if all_player % player != 0 or all_player < player:
        return {"code":2601, "msg":"all_player error", "data":{}}
    all_round = int(all_round)
    if all_round not in (8, 16, 10, 20):
        return {"code":2602, "msg":"all_round error", "data":{}}
    
    db = dao.Game_DB()
    rules = {}
    if rule:
        for r in rule.split(","):
            k, v = r.split("=")
            rules[k] = v
    game_des = config.GAME_TYPE_NAME.get(game_type, "")
    game_des += u" %s局" % all_round
    horse = int(rules.get("horse", 0))
    if game_type == 'pdk':
        must_put = rules.get("must_put", "y")
        release_duty = rules.get("release_duty", "y")
        closed_double = rules.get("closed_double", "y")
        if must_put == 'y':
            game_des = u"有牌必出 炸弹立结 放走包赔 全关加倍"
        else:
            game_des = u"可不出 炸弹立结 放走包赔 全关加倍" 
    else:
        if horse:
            game_des += u"%s马" % horse
        grab_bar_win = rules.get("grab_bar_win")
        if grab_bar_win == 'y':
            game_des += u",可抢杠胡"
        bar_win_duty = rules.get("bar_win_duty")
        if bar_win_duty == 'y':
            game_des += u",杠爆全包"
        seven_pair_win = rules.get("seven_pair_win")
        if seven_pair_win == 'y':
            game_des += u",可七对胡"
    i, gid = db.add_game(cid, name, game_type, player, all_round, all_player, game_des)
    for k, v in rules.iteritems():
        db.add_game_rule(gid, k, v)
        
    return {"code":0, "msg":"ok", "data":{"gid":gid}}

def enroll_game(gid, bid, uid):
    db = dao.Game_DB()
    game = db.get_game(gid)
    if not game:
        return {"code":2611, "msg":"牌局不存在"}
    status = game['status']
    if status == 2:
        return {"code":2612, "msg":"牌局已结束"}
    player = int(game['player'])
    all_player = int(game['all_player'])
    now_player = db.get_game_count(gid)['c']
    logging.info("%s,%s" % (now_player, all_player))
    if now_player >= all_player:
        return {"code":2613, "msg":"牌局人数已满,不能再报名"}
    
    joined_game = db.get_joined_game(uid)
    if joined_game:
        return {"code":2614, "msg":"您已报名,不能再报名"}
    joined_room = db.get_joined_room(bid, uid)
    if joined_room:
        return {"code":2615, "msg":"您已在其他房间游戏进行中,请先退出"}
    
    cid = game['cid']
    myrole = db.get_myrole(cid, uid)
    if myrole:
        verify = myrole['verify']
        role = myrole['role']
        if role !=0:
            return {"code":2616, "msg":"管理员不能报名"}
        if verify != 2:
            return {"code":2617, "msg":"你还没有报名参与牌局的资格"}    
    
    club = db.get_club(cid)
    bid = club['bid']
    admin = club['admin']
    game_type = game['game_type']
    all_round = int(game['all_round'])
    if all_round == 8:
        card = 1
    elif all_round == 16:
        card = 2
    else:
        return {"code":1301, "msg":"牌局创建错误"}
    ip = get_client_ip()
    db.add_game_member(gid, uid, ip)
    
    rules = {}
    game_rule = db.game_rule(gid)
    for r in game_rule:
        k = r['param']
        v = r['value']
        rules[k] = v
    
    joined_room = 0
    if (now_player+1) == all_player:
        #开始创建房间,分配房间
        game_members = db.game_members(gid)
        game_members = list(game_members)
        random.shuffle(game_members)
        room_num = all_player / player
        for i in range(room_num):
            (n, rid) = db.add_room(bid, game_type, admin, all_round, card, player, gid, 0, 1, 1, game['game_des'])
            
            for j in range(player):
                idx = i * room_num + j
                member = game_members[idx]
                ip = member['ip']
                p_uid = member['uid']
                if str(p_uid) == uid:
                    joined_room = rid
                if j == 0:
                    room_info = {"gid":gid,"cid":cid, "status":"", "admin":admin, "dealer":p_uid, "bid":bid, "last_get_user":p_uid, "game_round":1, "all_round":all_round, "card":card, "game_type":game_type, "horse":rules.get('horse', 'n'), "grab_bar_win":rules.get('grab_bar_win', 'n'), "grab_bar_duty":rules.get('grab_bar_duty', 'n'), "bar_win_duty":rules.get('bar_win_duty', 'n'), "seven_pair_win":rules.get('seven_pair_win', 'n')}
                    _r.hmset("r:%s" % rid, room_info)
                
                db.add_player(0, gid, rid, p_uid, 0, 'n', ip, '', '', j+1)
                _r.lpush("r:%s:p" % rid, p_uid)
                _r.hset("%s_%s" %(bid, p_uid), "rid", rid)
    return {"code":0, "msg":"操作成功", "data":{"rid":joined_room}}

def joined_rid(bid, uid):
    db = dao.Game_DB()
    joined_room = db.get_joined_rid(bid, uid)
    if joined_room:
        rid = joined_room['rid']
        code = 0
        if joined_room['mid']:
            msg = u"比赛开始,请准备进入房间"
        elif joined_room['gid']:
            msg = u"俱乐部牌局开始,请准备进入房间"
        else:
            msg = u"游戏开始,请准备进入房间"
    else:
        rid = 0
        code = 2521
        msg = ""
    return {"code":code, "msg":msg, "data":{"rid":rid}}

def quit_club(cid, bid, uid, pwd):
    db = dao.Game_DB()
    get_joined_game = db.get_joined_game(uid)
    if get_joined_game:
        {"code":2531, "msg":"您报名了牌局,不可退出俱乐部"}
    db.quit_club(cid, uid)
    db.update_join_user(bid, cid, -1)
    return {"code":0, "msg":"退出成功"}

def dismiss_club(cid, bid, uid, pwd):
    db = dao.Game_DB()
    club = db.get_club(cid)
    if not club or str(club['admin']) != uid:
        return {"code":2541, "msg":"你不是创建者,不能解散"}
    start_game = db.club_games(cid, 1)
    nostart_game = db.club_games(cid, 0)
    if start_game or nostart_game:
        return {"code":2542, "msg":"俱乐部有牌局,不可解散"}
    db.dismiss_club(cid, bid, uid)
    return {"code":0, "msg":"解散成功"}

def create_room(cp, cv, bid, uid, pwd, player, game_type, all_round, gps_lat, gps_lon, rule):
    ip = get_client_ip()
    all_round = int(all_round)
    if all_round in (8, 10):
        card = 1
    elif all_round in (16, 20):
        card = 2
    else:
        return {"code":1100, "msg":"all_round error"}
    
    rules = {}
    if rule:
        for r in rule.split(","):
            k, v = r.split("=")
            rules[k] = v
    horse = int(rules.get("horse", 0))
    grab_bar_win = rules.get("grab_bar_win", "n")
    grab_bar_duty = rules.get("grab_bar_duty", "n")
    bar_win_duty = rules.get("bar_win_duty", "n")
    seven_pair_win = rules.get("seven_pair_win", "n")
    player = int(player)
    if game_type == 'pdk':
        player = 3
    else:
        player = 4
    db = dao.Game_DB()
    user_info = db.user_info(bid, uid)
    get_joined_room = db.get_joined_room(bid, uid)
    if get_joined_room:
        return {"code":1100, "msg":"请先退出之前加入的房间"}
        #if str(get_joined_room['admin']) != uid:
        #    return {"code":1100, "msg":"请先退出之前加入的房间"}
        #return {"code":0, "msg":"ok", "data":{"sex":user_info['sex'], "ip":ip, "base_score":1000, "rid":get_joined_room['rid'], "share_url":"http://wap.99ok.com.cn/?rid=%s" % get_joined_room['rid'], "share_title":u"麻将<推倒胡>房间号:【%s】 【点击进入】" % get_joined_room['rid'], "share_des":u"%s马, %s局, 可七对,十三幺" % (horse, all_round)}}\
    row = db.enrolled_match(bid, uid)
    if row:
        return {"code":2716, "msg":"请先完成其他未完成的比赛", "data":{}}
    
    if user_info['card'] < card:
        return {"code":1101, "msg":"您的账户房卡不足"}
    try:
        must_put = 'y'
        black_three_first = 'n'
        card_warning = '1'
        share_des = u""
        if game_type == 'pdk':
            must_put = rules.get("must_put", "y")
            #release_duty = rules.get("release_duty", "y")
            #closed_double = rules.get("closed_double", "y")
            black_three_first = rules.get("black_three_first", "n")
            card_warning = rules.get("card_warning", "1")
            if not card_warning.isdigit():
                return {"code":1101, "msg":"请选择正确的报牌张数"}
            if must_put == 'y':
                share_des = u"有牌必出 炸弹立结 放走包赔 全关加倍"
            else:
                share_des = u"可不出 炸弹立结 放走包赔 全关加倍" 
            if black_three_first == "y":
                share_des += u" 首局先出黑桃3"
            share_des += u" %s张报牌" % card_warning
        else:
            horse = rules.get("horse", 0)
            if horse:
                share_des += u"%s马,%s局" % (horse, all_round)
            else:
                share_des += u"无马,%s局" % all_round
            if rules.get("seven_pair_win") == 'y':
                share_des += u",可胡七对"
            if rules.get("grab_bar_win") == 'y':
                share_des += u",可抢杠胡"
            if rules.get("bar_win_duty") == 'y':
                share_des += u",杠爆全包"
                
        # 创建房间
        (i, rid) = db.add_room(bid, game_type, uid, all_round, card, player, 0, 0, 1, 1, share_des)
        for k, v in rules.iteritems():
            db.add_room_rule(rid, k, v)
        game_type_name = config.GAME_TYPE_NAME.get(game_type, game_type)
        share_title = game_type_name
        share_title += u" 房间号:【%s】 【点击进入】" % rid
        
        # 添加房主玩家
        seat = 1
        base_score = 1000
        db.add_player(0, 0, rid, uid, 1, 'y', ip, gps_lat, gps_lon, seat, base_score)
        # 创建其他玩家座位
        for seat in range(2, player + 1):
            db.add_player(0, 0, rid, 0, 0, 'n', '', '', '', seat)
        if not nsq_pub("status", {"b":bid, "u":str(uid), "d":{"act":"create_room", "uid":uid, "rid":rid, "bid":bid, "player":player, "card":card, "all_round":all_round, "game_type":game_type, "horse":horse, "grab_bar_win":grab_bar_win, "grab_bar_duty":grab_bar_duty, "bar_win_duty":bar_win_duty, "seven_pair_win":seven_pair_win, "must_put":must_put, "black_three_first":black_three_first, "card_warning":card_warning}}):
            db.res = False
            return {"code":1102, "msg":"处理超时"}
        share_url = "%s/index/club?rid=%s" % (config.WAP, rid)
        auto_put = "n"
        return {"code":0, "msg":"ok", "data":{"all_round":all_round,"seat":1, "auto_put":auto_put, "rules":rules, "game_type_name":game_type_name, "game_type":game_type, "sex":user_info['sex'], "ip":ip, "base_score":base_score, "rid":rid, "share_url":share_url, "share_title":share_title, "share_des":share_des}}
    except:
        db.res = False
        logging.error("create room error:", exc_info=True)
        return {"code":1103, "msg":"创建失败"}

def join_room(cp, cv, bid, uid, pwd, rid, gps_lat, gps_lon):
    ip = get_client_ip()
    db = dao.Game_DB()
    user_info = db.user_info(bid, uid)
    if not user_info:
        return {"code":1200, "msg":"uid不存在"} 
    room_info = db.get_room(rid, bid)
    if not room_info:
        return {"code":1200, "msg":"该房间不存在"}
    if room_info['flag'] != 'y':
        return {"code":1201, "msg":"该房间已结束"}
    room = _r.hgetall("r:%s" % rid)
    if room.get('dealer'):
        room_info['dealer'] = int(room['dealer'])
        room_info['game_round'] = int(room['game_round'])
    else:
        room_info['dealer'] = room_info['admin']
    room_info.pop("ctime")
    get_joind_room = db.get_joined_room(bid, uid)
    if get_joind_room:
        # 重返房间
        if get_joind_room['rid'] != int(rid):
            return {"code":1202, "msg":"该帐号已在其他房间,请先退出"}
        seat = get_joind_room['seat']
        i = db.return_room(rid, seat, uid, 0, 'y', ip, gps_lat, gps_lon)
        i = 1
    else:
        # 新加入房间
        row = db.get_free_seat(rid)
        if not row:
            return {"code":1202, "msg":"该房间人员已满"}
        seat = row['seat']
        i = db.join_room(rid, seat, uid, 0, 'y', ip, gps_lat, gps_lon)
    if i != 1:
        db.res = False
        return {"code":1203, "msg":"进入房间失败"}
    match_id = room_info['mid']
    gid = room_info['gid']
    ranking = "0"
    if match_id:
        match_member_info = db.match_member_info(match_id, uid)
        score = match_member_info['score']
        auto_put = "y"
        room_type = "match"
        
        match = db.match_info(bid, match_id)
        mround = match['mround'] - 1
    else:
        mround = 0
        score = 1000
        auto_put = "n"
        if gid:
            room_type = "club"
        else:
            room_type = "card"
        
    if not nsq_pub("status", {"b":bid, "u":str(uid), "d":{"ranking":ranking, "sex":user_info['sex'],"act":"join_room", "uid":uid, "rid":rid, "bid":bid, "ip":ip, "gps_lat":gps_lat, "gps_lon":gps_lon, "seat":seat, "score":score, "head":user_info['head'], "name":user_info['name']}}):
        db.res = False
        return {"code":1204, "msg":"处理超时"}
    # 获取房间所有玩家信息
    players = db.query_room_players(rid, bid)
    for p in players:
        pranking = "0"
        p['ranking'] = pranking
    game_type = room_info['game_type']
    rules = {}
    if room_info["gid"]:
        rows = db.game_rule(room_info["gid"])
    elif match_id:
        rules = {"horse":0, "grab_bar_win":"y", "grab_bar_duty":"y", "bar_win_duty":"n", "seven_pair_win":"y"}
        if game_type == 'pdk':
            rules = {"must_put":"y", "release_duty":"y", "closed_double":"y", "show_left_card":"n", "black_three_first":"n", "card_warning":1}
        rows = []
    else:    
        rows = db.room_rule(rid)
    for row in rows:
        k = row['param']
        rules[k] = row['value']
    
    game_type_name = config.GAME_TYPE_NAME.get(game_type, game_type)
    share_title = game_type_name
    share_title += u" 房间号:【%s】 【点击进入】" % rid
    share_des = room_info['des']
    share_url = "%s/index/club?rid=%s" % (config.WAP, rid)
    return {"code":0, "msg":"ok", "data":{"ranking":ranking, "room_type":room_type, "game_type_name":game_type_name, "game_type":game_type, "auto_put":auto_put, "rules":rules,"base_score":score, "room_info":room_info, "players":players, "seat":seat, "share_url":share_url, "share_title":share_title, "share_des":share_des}}

def quit_room(cp, cv, bid, uid, pwd, rid):
    rid = int(rid)
    db = dao.Game_DB()
    room_info = db.get_room(rid, bid)
    if not room_info:
        return {"code":1300, "msg":"该房间不存在"}
    if room_info['flag'] == 'n':
        return {"code":0, "msg":"退出成功"}
    get_joined_room = db.get_joined_room(bid, uid)
    if not get_joined_room:
        return {"code":1301, "msg":"该帐号未进入房间无需退出"}
    status = _r.hget("r:%s" % rid, "status")
    if status:
        return {"code":1302, "msg":"游戏进行中,不能退出房间"}
    if room_info['mid']:
        return {"code":1303, "msg":"比赛进行中,不能退出房间"}
    if room_info['gid']:
        return {"code":1303, "msg":"牌局进行中,不能退出房间"}
    if room_info['admin'] == long(uid):
        i = db.admin_quit_room(rid, uid)
        joined_room = rid
    else:
        i = db.quit_room(rid, uid)
        joined_room = ""
    if i != 1:
        db.res = False
        return {"code":1303, "msg":"房间退出失败"}
    if not nsq_pub("status", {"b":bid, "u":str(uid), "d":{"act":"quit_room", "uid":uid, "rid":rid, "bid":bid}}):
        db.res = False
        return {"code":1304, "msg":"处理超时"}
    return {"code":0, "msg":"ok", "data":{"joined_room":joined_room}}

def dismiss_room(cp, cv, bid, uid, pwd, rid):
    rid = int(rid)
    db = dao.Game_DB()
    room_info = db.get_room(rid, bid)
    if not room_info:
        return {"code":1400, "msg":"该房间不存在"}
    if room_info['admin'] != long(uid):
        return {"code":1401, "msg":"你不是该房间的房主,不能解散"}
    room_player_cnt = db.room_player_cnt(rid)
    if room_player_cnt['player'] == room_info['player']:
        return {"code":1401, "msg":"游戏已准备,不能解散"}
    i = db.dismiss_room(rid, bid, uid)
    if i != 1:
        db.res = False
        return {"code":1302, "msg":"房间退出失败"}
    if not nsq_pub("status", {"b":bid, "u":str(uid), "d":{"act":"dismiss_room", "uid":uid, "rid":rid, "bid":bid}}):
        db.res = False
        return {"code":1303, "msg":"处理超时"}
    return {"code":0, "msg":"ok"}
    
def game_des(cp, cv, bid, uid):
    db = dao.Game_DB()
    conf_list = db.get_game_des()
    game_data = {}
    for game in conf_list:
        game_type = game['game_type']
        game_data[game_type] = {"name":game['name'], "des":game['des']}
    return {"code":0, "msg":"ok", "data":{'game_data':game_data}}

def feedback(bid, uid, content):
    db = dao.Game_DB()
    db.add_feedback(bid, uid, content)
    return {"code":0, "msg":"ok"}

def game_start(rid, bid):
    nsq_pub("game", {"b":"szjt", "u":"", "t":"game", "d":{"act":"game_start", "rid":rid}})
    return "ok"

def room_log(bid, uid):
    db = dao.Game_DB()
    rows = db.room_log(bid, uid)
    return {"code":0, "msg":"ok", "data":{"room_log":rows}}

def room_log_detail(bid, uid, rid):
    db = dao.Game_DB()
    rows = db.room_log_detail(rid)
    return {"code":0, "msg":"ok", "data":{"game_log_detail":rows}}

def id_auth(bid, uid, id_no, name):
    idcard_error = util.checkIdcard(id_no)
    if idcard_error:
        return {"code":2651, "msg":"身份证号码格式错误", "data":{}}
    db = dao.Game_DB()
    user_auth = db.user_auth(bid, uid)
    if user_auth:
        return {"code":2652, "msg":"你已提交实名认证信息,请勿重复提交", "data":{}}
    db.update_user_auth(bid, uid, id_no, name)
    return {"code":0, "msg":"提交成功", "data":{}} 
    
def create_match(bid, uid, game_type, score, all_player, start_time, name, des):
    if not name:
        return {"code":2700, "msg":"请输入比赛名称", "data":{}}
    if not all_player or int(all_player) < 3:
        return {"code":2701, "msg":"请输入比赛正确的比赛人数", "data":{}} 
    start_time = urllib.unquote_plus(start_time)
    db = dao.Game_DB()
    user_info = db.user_info(bid, uid)
    if user_info['mcard'] < int(all_player):
        return {"code":2701, "msg":"赛卡不足,不能创建比赛", "data":{}}
    row = db.unauth_match(bid, uid)
    if row['num'] >= 3:
        return {"code":2702, "msg":"之前创建的3个比赛未审核通过,不能再创建", "data":{}}
    if not util.check_time(start_time):
        return {"code":2703, "msg":"请输入有效的比赛开始时间", "data":{}}
    i, mid = db.add_match(bid, uid, game_type, score, all_player, start_time, name, des)
    if i != 1:
        return {"code":2704, "msg":"创建失败", "data":{}}
    #db.join_match(bid, uid, mid, 2, 0, 1)
    #db.deduct_mcard(bid, uid, 1)
    return {"code":0, "msg":"创建成功", "data":{"mid":mid}}

def join_match(bid, uid, mid, pid):
    db = dao.Game_DB()
    match = db.match_info(bid, mid)
    if not match:
        return {"code":2711, "msg":"比赛不存在", "data":{}}
    if match['status'] in (4, 5):
        return {"code":2712, "msg":"比赛未审核,不能加入", "data":{}}
    elif match['status'] in (1, 2):
        return {"code":2712, "msg":"比赛已经开始,不能加入", "data":{}}
    elif match['status'] == 3:
        return {"code":2712, "msg":"比赛已经结束,不能加入", "data":{}}
    
    match_member_cnt = db.match_member_cnt(mid)
    join_user = match_member_cnt['number']
    if join_user >= match['all_player']:
        return {"code":2713, "msg":"比赛人员已满,不能加入", "data":{}}
    if str(match['admin']) != pid:
        match_member_info = db.match_member_info(mid, pid)
        if not match_member_info:
            return {"code":2714, "msg":"推荐人不在比赛中,请重新输入", "data":{}}
        elif match_member_info['role'] == 0:
            return {"code":2715, "msg":"推荐人不是管理员,请重新输入", "data":{}}
    row = db.enrolled_match(bid, uid)
    if row:
        return {"code":2716, "msg":"请先完成其他未完成的比赛", "data":{}}
    i = db.join_match(bid, uid, mid, 0, pid, 0)
    return {"code":0, "msg":"已提交报名比赛申请,等待审核", "data":{}}

def quit_match(bid, uid, mid):
    db = dao.Game_DB()
    match = db.match_info(bid, mid)
    if not match:
        return {"code":2711, "msg":"比赛不存在", "data":{}}
    match_member_info = db.match_member_info(mid, uid)
    if not match_member_info:
        return {"code":2713, "msg":"推荐人不在比赛中,请重新输入", "data":{}}
    if match_member_info['verify'] == 1:
        return {"code":2714, "msg":"您已申请通过不能退出", "data":{}}
    if match['status'] in (1, 2):
        return {"code":2712, "msg":"比赛已经开始,不能退出", "data":{}}
    elif match['status'] == 3:
        return {"code":2712, "msg":"比赛已经结束,不能退出", "data":{}}
    i = db.quit_match(bid, uid, mid)
    return {"code":0, "msg":"退出成功", "data":{}}

def mine_match(bid, uid):
    db = dao.Game_DB()
    rows = db.my_match(bid, uid)
    for match in rows:
        match['role'] = 2
        match['edit_flag'] = 'y'
        match['start_time'] = str(match['start_time'])
        game_type = match['game_type']
        match['game_type_name'] = config.GAME_TYPE_NAME.get(game_type, game_type)
        mid = match['mid']
        match['share_title'] = u"快来参加我的比赛:%s 【比赛编码:%s】" % (match['name'], mid)
        match['share_des'] = match['des']
        match['share_url'] = "%s/index/club?mid=%s&pid=%s" % (config.WAP, mid, uid)
    return {"code":0, "msg":"ok", "data":{"mine_match":rows}}

def joined_match(bid, uid):
    db = dao.Game_DB()
    rows = db.joined_match(bid, uid)
    for match in rows:
        match['edit_flag'] = 'n'
        match['start_time'] = str(match['start_time'])
        game_type = match['game_type']
        match['game_type_name'] = config.GAME_TYPE_NAME.get(game_type, game_type)
        mid = match['mid']
        match['share_title'] = u"快来参加我的比赛:%s 【比赛编码:%s】" % (match['name'], mid)
        match['share_des'] = match['des']
        match['share_url'] = "%s/index/club?mid=%s&pid=%s" % (config.WAP, mid, uid)
    return {"code":0, "msg":"ok", "data":{"joined_match":rows}}

def match_info(bid, uid, mid):
    db = dao.Game_DB()
    match = db.match_info(bid, mid)
    if not match:
        return {"code":2700, "msg":"ok", "data":{"match_info":match}}
    else:
        match['ctime'] = str(match['ctime'])
        match['start_time'] = str(match['start_time'])
        game_type = match['game_type']
        if game_type == 'pdk':
            player = 3
        else:
            player = 4
        match_member_cnt = db.match_member_cnt(mid)
        match['join_user'] = match_member_cnt['number']
        match['online_user'] = match_member_cnt['online_user']
        less_user = player - (match_member_cnt['number'] % player)
        if less_user == player and match_member_cnt['number'] >= player:
            match['less_user'] = 0
        else:
            match['less_user'] = less_user
            
        match['share_title'] = u"快来参加我的比赛:%s 【比赛编码:%s】" % (match['name'], mid)
        match['share_des'] = match['des']
        match['share_url'] = "%s/index/club?mid=%s&pid=%s" % (config.WAP, mid, uid)
        
        match['game_type_name'] = config.GAME_TYPE_NAME.get(game_type, game_type)
        if str(match['admin']) == uid:
            role = 2
        else:
            match_member_info = db.match_member_info(mid, uid)
            if match_member_info:
                role = match_member_info['role']
            else:
                role = 0
        match['role'] = role
        ing_room = db.match_ing_room(mid, match['mround'])
        match['left_room'] = ing_room['num']
    return {"code":0, "msg":"ok", "data":{"match_info":match}} 

def match_edit(bid, uid, mid, name, des, all_player, start_time):
    db = dao.Game_DB()
    match = db.match_info(bid, mid)
    if not match:
        return {"code":2716, "msg":"比赛不存在", "data":{}} 
    if str(match['admin']) != uid:
        return {"code":2717, "msg":"你不是创建者不能设置管理员", "data":{}}
    if not start_time or start_time == 'None':
        start_time = str(match['start_time'])
    db.update_match_info(bid, mid, name, des, all_player, start_time)
    return {"code":0, "msg":"操作成功", "data":{}}
        
def list_match_member(bid, uid, mid):
    db = dao.Game_DB()
    match = db.match_info(bid, mid)
    if str(match['admin']) == uid:
        admin_flag = True
    else:
        admin_flag = False
    rows = db.match_member(bid, mid, uid, admin_flag)
    return {"code":0, "msg":"ok", "data":{"match_member":rows}}

def del_match_member(bid, uid, mid, member):
    db = dao.Game_DB()
    match = db.match_info(bid, mid)
    if str(match['admin']) != uid:
        return {"code":2721, "msg":"你不是创建者不能设置管理员", "data":{}} 
    if match['status'] == 1:
        return {"code":2761, "msg":"本轮比赛未结束,不能操作"}
    rows = db.del_match_member(mid, member)
    rows = db.match_member(bid, mid, uid, True)
    return {"code":0, "msg":"操作成功", "data":{}}

def set_match_manager(bid, uid, mid, member):
    db = dao.Game_DB()
    match = db.match_info(bid, mid)
    if str(match['admin']) != uid:
        return {"code":2721, "msg":"你不是创建者不能设置管理员", "data":{}}
    if match['status'] == 1:
        return {"code":2761, "msg":"本轮比赛未结束,不能操作"}
    rows = db.set_match_manager(bid, member, mid)
    rows = db.match_member(bid, mid, uid, True)
    return {"code":0, "msg":"操作成功", "data":{"match_member":rows}}

def unset_match_manager(bid, uid, mid, member):
    db = dao.Game_DB()
    match = db.match_info(bid, mid)
    if str(match['admin']) != uid:
        return {"code":2721, "msg":"你不是创建者不能设置管理员", "data":{}} 
    rows = db.unset_match_manager(bid, member, mid)
    rows = db.match_member(bid, mid, uid, True)
    return {"code":0, "msg":"操作成功", "data":{"match_member":rows}}

def verify_match_member(bid, uid, mid, member, verify):
    db = dao.Game_DB()
    match = db.match_info(bid, mid)
    if str(match['admin']) != uid:
        #return {"code":2731, "msg":"你不是创建者不能设置管理员", "data":{}}
        member_info = db.match_member_info(mid, uid)
        if member_info['role'] != 1:
            return {"code":2731, "msg":"你不是管理员不能审核", "data":{}}
        admin_flag = False
    else:
        admin_flag = True
    if match['status'] == 1:
        return {"code":2761, "msg":"本轮比赛进行中,不能操作"}
    if verify == '0':
        db.del_match_member(mid, member)
    else:
        db.verify_match_member(mid, member)
    rows = db.match_member(bid, mid, uid, admin_flag)
    return {"code":0, "msg":"操作成功", "data":{"match_member":rows}}

def start_match(bid, uid, mid):
    db = dao.Game_DB()
    match = db.match_info(bid, mid)
    if str(match['admin']) != uid:
        return {"code":2741, "msg":"你不是创建者不能设置管理员", "data":{}}
    ing_room = db.match_ing_room(mid, 1)
    if ing_room['num'] > 0:
        return {"code":2742, "msg":"比赛正在进行不能操作", "data":{}}
    if match['status'] != 0:
        return {"code":2740, "msg":"比赛未招募中,不能开始", "data":{}}
    admin = match['admin']
    game_type = match['game_type']
    if game_type == 'pdk':
        player = 3
        all_round = 3
    else:
        player = 4
        all_round = 4
    
    card = 0
    match_players = db.match_player(bid, mid)
    all_player = len(match_players)
    if all_player % player != 0 or all_player <player:
        return {"code":2743, "msg":"参数人员不满", "data":{}}
    
    match_players = list(match_players)
    random.shuffle(match_players)
    room_num = all_player / player
    mround = 1
    if game_type == 'pdk':
        base_score = 1
    else:
        base_score = 100
    for i in range(room_num):
        (n, rid) = db.add_room(bid, game_type, admin, all_round, 0, player, 0, mid, mround, base_score)
        
        for j in range(player):
            idx = i * player + j
            member = match_players[idx]
            ip = member['ip']
            p_uid = member['uid']
            if j == 0:
                room_info = {"mid":mid, "gid":"","cid":"", "status":"", "admin":admin, "dealer":p_uid, "bid":bid, "last_get_user":p_uid, "game_round":1, "all_round":all_round, "card":card, "game_type":game_type, "horse":0, "grab_bar_win":"y", "grab_bar_duty":"y", "bar_win_duty":"n", "seven_pair_win":"y"}
                logging.info(room_info)
                _r.hmset("r:%s" % rid, room_info)
                _r.hset("%s_%s" % (bid, p_uid), "rid", rid)
            score = 0
            db.add_player(mid, 0, rid, p_uid, 0, 'n', ip, '', '', j+1, score)
            _r.rpush("r:%s:p" % rid, p_uid)
            _r.hset("%s_%s" %(bid, p_uid), "rid", rid)
        nsq_pub("status", {"b":bid,"u":str(uid), "t":"game", "d":{"act":"start_match", "mid":mid, "rid":rid}})
    db.update_match_status(mid, 1)
    db.deduct_mcard(bid, uid, all_player)
    nsq_pub("total", {"act":"deduct_mcard", "bid":bid, "uid":admin, "card":all_player, "mid":mid})
    return {"code":0, "msg":"操作成功", "data":{}}

def pause_match(bid, uid, mid):
    db = dao.Game_DB()
    match = db.match_info(bid, mid)
    if str(match['admin']) != uid:
        return {"code":2751, "msg":"你不是创建者不能操作", "data":{}}
    if match['status'] != 1:
        return {"code":2752, "msg":"比赛不在进行中,不能暂停", "data":{}}
    if match['mround'] < 3:
        return {"code":2753, "msg":"比赛第三轮后才可以暂停", "data":{}}
    db.update_match_status(mid, 2)
    return {"code":0, "msg":"操作成功", "data":{}}

def stop_match(bid, uid, mid):
    db = dao.Game_DB()
    match = db.match_info(bid, mid)
    if str(match['admin']) != uid:
        return {"code":2751, "msg":"你不是创建者不能操作", "data":{}}
    db.update_match_status(mid, 3)
    nsq_pub("status", {"b":bid,"u":str(uid), "t":"game", "d":{"act":"stop_match", "mid":mid, }})
    return {"code":0, "msg":"操作成功", "data":{}}

def all_match(bid, uid):
    db = dao.Game_DB()
    enrolled_match = db.enrolled_match(bid, uid)
    if enrolled_match:
        joined_mid = enrolled_match['mid']
    else:
        joined_mid = 0
    rows = db.all_match(bid, uid)
    for match in rows:
        if match['mid'] == joined_mid:
            match['joined_flag'] = 'y'
            match['verify'] = enrolled_match['verify']
        else:
            match['joined_flag'] = 'n'
            match['verify'] = 0
        match['role'] = 0
        match['edit_flag'] = 'n'
        game_type = match['game_type']
        match['game_type_name'] = config.GAME_TYPE_NAME.get(game_type, game_type)
        mid = match['mid']
        match['share_title'] = u"快来参加我的比赛:%s 【比赛编码:%s】" % (match['name'], mid)
        match['share_des'] = match['des']
        match['share_url'] = "%s/index/club?mid=%s&pid=%s" % (config.WAP, mid, uid)
        match['start_time'] = str(match['start_time'])
    return {"code":0, "msg":"ok", "data":{"all_match":rows}}

def keep_match(bid, uid, mid):
    #暂停后重新恢复继续比赛
    #晋级和复活的人员开始新的房间
    db = dao.Game_DB()
    match = db.match_info(bid, mid)
    if str(match['admin']) != uid:
        return {"code":2751, "msg":"你不是创建者不能操作", "data":{}}
    if match['status'] != 2:
        return {"code":2752, "msg":"比赛没有暂停,不能继续", "data":{}}
    mround = match['mround']
    admin = match['admin']
    game_type = match['game_type']
    ing_room = db.match_ing_room(mid, mround)
    if ing_room['num'] > 0:
        return {"code":2753, "msg":"比赛正在进行不能操作", "data":{}}
    
    if game_type == 'pdk':
        player = 3
        all_round = 3
    else:
        player = 4
        all_round = 4
    card = 0
    match_players = db.match_keep_palyer(mid)
    all_player = len(match_players)
    if all_player % player != 0:
        return {"code":0, "msg":"参数人员不满", "data":{}}
    
    base_score = 100 * 3 ** (mround-1)
    if all_player == player:
        #总决赛
        all_round = 9
    match_players = list(match_players)
    random.shuffle(match_players)
    room_num = all_player / player
    
    for i in range(room_num):
        (n, rid) = db.add_room(bid, game_type, admin, all_round, 0, player, 0, mid, mround, base_score)
        
        for j in range(player):
            idx = i * player + j
            member = match_players[idx]
            ip = member['ip']
            p_uid = member['uid']
            if j == 0:
                room_info = {"mid":mid, "gid":"","cid":"", "status":"", "admin":admin, "dealer":p_uid, "bid":bid, "last_get_user":p_uid, "game_round":1, "all_round":all_round, "card":card, "game_type":game_type, "horse":0, "grab_bar_win":"y", "grab_bar_duty":"y", "bar_win_duty":"n", "seven_pair_win":"y"}
                _r.hmset("r:%s" % rid, room_info)
            
            db.add_player(mid, 0, rid, p_uid, 0, 'n', ip, '', '', j+1, member['score'])
            _r.rpush("r:%s:p" % rid, p_uid)
            _r.hset("%s_%s" %(bid, p_uid), "rid", rid)
            msg = u"恭喜你晋级下一轮,比赛继续"
            nsq_pub("response", {"b":bid, "u":str(p_uid), "t":"game", "d":{"act":"match_keep", "msg":msg, "rid":rid}})
            
        nsq_pub("status", {"b":bid,"u":str(uid), "t":"game", "d":{"act":"start_match", "mid":mid, "rid":rid}})
    db.update_match_status(mid, 1)
    return {"code":0, "msg":"操作成功", "data":{}}

def revive_apply(bid, uid, mid, member):
    db = dao.Game_DB()
    match = db.match_info(bid, mid)
    if match['status'] == 1:
        return {"code":2761, "msg":"本轮比赛未结束,不能复活"}
    if match['vive_flag'] != 'y':
        return {"code":2762, "msg":"本比赛不支持复活"}
    if str(match['admin']) != uid:
        return {"code":2763, "msg":"只有赛主才可以复活玩家"}
        #match_member_info = db.match_member_info(mid, uid)
        #if match_member_info['role'] == 0:
        #    return {"code":2763, "msg":"只有管理员才可以给用户申请复活"}
    
    #复活用户以最后一名分数
    match_member_info = db.match_member_info(mid, member)
    if match_member_info['res'] != 0:
        return {"code":2764, "msg":"该用户没被淘汰不能复活"}
    
    user_info = db.user_info(bid, uid)
    if user_info['point'] < 1:
        return {"code":2765, "msg":"新毛值不足,请先充值"}
    
    last_member = db.match_last_member(bid, mid)
    #if match_member_info['score'] < last_member['score']:
    #    score = last_member['score']
    #else:
    #    score = None
    score = last_member['score']
    db.revive_apply(mid, member, score)
    point = 1
    db.deduct_point(bid, uid, point)
    if str(match['admin']) != uid:
        admin_flag = False
    else:
        admin_flag = True
    rows = db.match_out_member(bid, mid, uid, admin_flag)
    return {"code":0, "msg":"操作成功", "data":{"out_member":rows}}

def match_out_member(bid, uid, mid):
    db = dao.Game_DB()
    match = db.match_info(bid, mid)
    if str(match['admin']) == uid:
        admin_flag = True
    else:
        admin_flag = False
    if match['vive_flag'] != 'y':
        admin_flag = False
        uid = '1'
    rows = db.match_out_member(bid, mid, uid, admin_flag)
    return {"code":0, "msg":"ok", "data":{"out_member":rows}}

def match_result(bid, uid, mid):
    db = dao.Game_DB()
    match = db.match_info(bid, mid)
    match_mround = match['mround']
    result = []
    user_info = db.user_info(bid, uid)
    if match['status'] in (1, 2, 3):
        #member_info = db.match_member_info(mid, uid)
        for mround in range(1, match_mround+1):
            #if str(match['admin']) == uid or member_info['role'] == 1:
            #    rows = db.match_score_log(mid, mround, bid)
            #    for idx, row in enumerate(rows):
            #        #row['mround'] = "%s/%s" %(mround, match_mround)
            #        row['mround'] = "%s" %mround
            #        row['ranking'] = str(idx + 1)
            #        result.append(row)
            #else:
            if 1:
                member_score = db.match_member_score(mid, mround, uid)
                if member_score:
                    score = str(member_score['score'])
                    ctime = str(member_score['ctime'])
                    member_ranking = db.match_membe_ranking(mid, mround, score, ctime)
                    ranking = str(member_ranking['num']+ 1) 
                else:
                    score = "-"
                    ranking = "-"
                data = {"mround":"%s" % mround, "score":score, "ranking":ranking, "uid":uid, "name":user_info['name']}
                result.append(data)
    del match['ctime']
    del match['start_time']

    return {"code":0, "msg":"ok", "data":{"result":result, "match_info":match}}

def match_result_detail(bid, uid, mid, mround):
    db = dao.Game_DB()
    rows = db.match_score_log(mid, mround, bid)
    for idx, row in enumerate(rows):
        row['mround'] = "%s" %(mround)
        row['ranking'] = str(idx + 1)
    return {"code":0, "msg":"ok", "data":{"result":rows}}

def current_ranking(bid, uid):
    db = dao.Game_DB()
    ongoing_match = db.ongoing_match(bid, uid)
    if not ongoing_match:
        msg = u"恭喜你现在排名在晋级范围内"
        return {"code":0, "msg":"ok", "data":{"mround":"1" , "score":100, "ranking":str(1), "msg":msg}}
    mid = ongoing_match['mid']
    mround = ongoing_match['mround']
    score = ongoing_match['user_score']
    endtime = str(ongoing_match['endtime'])
    
    member_ranking = db.current_ranking(mid, score, endtime)
    ranking = member_ranking['num']+ 1
    match_keep_palyer = db.match_keep_palyer(mid)
    mround_member = len(match_keep_palyer)
    next_num = cut_number(mround_member, 4, mround)
    if next_num > 0:
        if ranking == 1:
            msg = u"恭喜你现在排名第一"
        elif ranking <= next_num:
            msg = u"恭喜你现在排名在晋级范围内"
        else:
            row = db.middle_score(mid, next_num)
            msg = u"距离第%s名还差%s分" % (next_num, (row['score'] - score))
    else:
        if ranking == 1:
            msg = u"恭喜你现在排名第一"
        else:
            row = db.first_score(mid)
            msg = u"距离第%s名还差%s分" % (1, (row['score'] - score))
    return {"code":0, "msg":"ok", "data":{"mround":"%s" % mround, "score":score, "ranking":str(ranking), "msg":msg}}


def cut_number(n=100, m=4, mround=1):
    if mround == 1:
        if n % (m*2) == 0:
            return n/2
        elif n == m:
            return 0
    else:
        n /= 2
    if n < m:
        return 0
    elif n == m:
        return m
    j = 0
    for i in range(20):
        if n <= m*2**i:
            j = i
            break
    if mround == 1:
        return m*2**(j-1)
    p = n - m*2**(j-1)
    q = m*2**j - n
    if p > q:
        return m*2**j
    return m*2**(j-1)

def match_game_over(reader, bid, uid, data):
    mid = data.get("match_id")
    game_round = int(data['game_round'])
    db = dao.Game_DB()
    if mid:
        match = db.match_info(bid, mid)
        game_type = match['game_type']
        match_status = match['status']
        mround = match['mround']
        #不同轮数底分不同
        all_round = int(data['all_round'])
        #match_score = mround * match['score'] + all_round - game_round
        #mround_room = db.mround_room(mid, mround)
        #if mround_room['num'] == 1:
        #    match_score = 1200 + game_round - 1
        endtime = time.strftime("%Y-%m-%d %H:%M:%S")
        
        for ps in data['player_card']:
            member = ps['uid']
            #score = int(ps['score']) * match_score
            score = int(ps['score'])
            db.update_score(mid, member, score, endtime)
            db.add_match_log(mid, mround, data['rid'], game_round, member, score)
            logging.info(u"比赛:%s第%s轮房间;%s结束第%s小局,玩家:%s,分数:%s" % (mid, mround, data['rid'], game_round, member, score))
                    
def match_room_over(reader, bid, uid, data):
    mid = data.get("match_id")
    gid = data.get("gid")
    db = dao.Game_DB()
    if gid:
        db.update_game_status(gid)
        logging.info(u"俱乐部牌局结束:%s" % gid)
    if mid:
        logging.info(u"比赛中房间完成结束游戏:%s" % mid)
        match = db.match_info(bid, mid)
        game_type = match['game_type']
        match_status = match['status']
        mround = match['mround']
        ing_room = db.match_ing_room(mid, mround)
        ing_room_num = ing_room['num']
        for ps in data['player_stat']:
            member = ps['uid']
            member_info = db.match_member_info(mid, member)
            db.add_match_score(mid, mround, member, member_info['score'])
            logging.info(u"比赛:%s第%s轮,房间:%s结束,玩家:%s当前分数:%s" % (mid, mround, data['rid'], member, member_info['score']))
        
        #next_ing_room = db.match_ing_room(mid, mround+1)
        #next_room_num = next_ing_room['num']
        pre_round_players = db.pre_round_players(mid, mround)
        #推送通知
        for p in pre_round_players:
            p_uid = p['uid']
            msg = u"本轮比赛结束,请耐心等待其他玩家完成比赛以决定你的排名,祝您好运~"
            message = {"b":bid, "u":str(p_uid), "t":"game", "d":{"act":"match_room_over","left_room":ing_room_num, "msg":msg}}
            nsq_pub("response", message)
        
        if ing_room_num == 0:
            #当轮比赛结束,没有进行的房间
            #取出这一轮玩家人员,计算出来该晋级的人数,更新被淘汰的人员状态为0,晋级人员为1
            logging.info(u"比赛:%s第%s轮结束" % (mid, mround))
            #pre_round_players = db.match_keep_palyer(mid)
            
            if game_type == 'pdk':
                player = 3
                all_round = 3
            else:
                player = 4
                all_round = 4
            
            next_round_num = cut_number(len(pre_round_players), player, mround)
            if next_round_num:
                next_round_players = pre_round_players[:next_round_num]
                for p in next_round_players:
                    db.match_palyer_in(mid, p['uid'])
                    #msg = u"恭喜你晋级,可以进入下一轮"
                    #message = {"b":bid, "u":str(p['uid']), "t":"game", "d":{"act":"match_in", "msg":msg}}
                    #nsq_pub("response", message)
                out_players = pre_round_players[next_round_num:]
                j = 0
                for p in out_players:
                    j += 1
                    db.match_palyer_out(mid, p['uid'])
                    msg = u"很遗憾,您被淘汰"
                    ranking = j + next_round_num
                    message = {"b":bid, "u":str(p['uid']), "t":"game", "d":{"act":"match_out", "msg":msg, "ranking":ranking}}
                    nsq_pub("response", message)
            
                #更新比赛为开始下一轮
                mround += 1
                db.update_match_round(mid, mround)
                
                #判断比赛状态是否继续,分配房间,如果是总决赛all_round为9
                if match_status == 3:
                    #推送消息暂停比赛
                    for pre_player in pre_round_players:
                        msg = u"比赛结束~"
                        message = {"b":bid, "u":str(pre_player['uid']), "t":"game", "d":{"act":"match_over", "msg":msg}}
                        nsq_pub("response", message)
                elif match_status == 2:
                    #推送消息暂停比赛
                    for pre_player in next_round_players:
                        msg = u"恭喜你晋级下一轮,比赛暂停中,休息一下稍后再开始下一轮"
                        message = {"b":bid, "u":str(pre_player['uid']), "t":"game", "d":{"act":"match_pause", "msg":msg}}
                        nsq_pub("response", message)
                elif match_status == 1:
                    #分配房间
                    admin = match['admin']
                    card = 0
                    match_players = list(next_round_players)
                    all_player = len(match_players)
                    random.shuffle(match_players)
                    room_num = all_player / player
                    
                    base_score = 100 * 3 ** (mround-1)
                    #最后一轮总决赛
                    if all_player == player:
                        all_round = 9
                        
                    for i in range(room_num):
                        (n, rid) = db.add_room(bid, game_type, admin, all_round, 0, player, 0, mid, mround, base_score)
                        
                        for j in range(player):
                            idx = i * player + j
                            member = match_players[idx]
                            ip = member.get('ip','')
                            p_uid = member['uid']
                            if j == 0:
                                room_info = {"mid":mid, "gid":"","cid":"", "status":"", "admin":admin, "dealer":p_uid, "bid":bid, "last_get_user":p_uid, "game_round":1, "all_round":all_round, "card":card, "game_type":game_type, "horse":0, "grab_bar_win":"y", "grab_bar_duty":"y", "bar_win_duty":"n", "seven_pair_win":"y"}
                                _r.hmset("r:%s" % rid, room_info)
                            
                            db.add_player(mid, 0, rid, p_uid, 0, 'n', ip, '', '', j+1, member['score'])
                            _r.rpush("r:%s:p" % rid, p_uid)
                            _r.hset("%s_%s" %(bid, p_uid), "rid", rid)
                            msg = u"恭喜你晋级,可以进入下一轮"
                            message = {"b":bid, "u":str(p_uid), "t":"game", "d":{"act":"match_in", "msg":msg, "rid":rid}}
                            nsq_pub("response", message)
                            logging.info(u"用户晋级:%s,%s,%s" % (mid, rid, p_uid))
                            
                        nsq_pub("status", {"b":bid,"u":str(uid), "t":"game", "d":{"act":"start_match", "mid":mid, "rid":rid}})
            else:
                db.match_over(mid)
                rk = 0
                for pre_player in pre_round_players:
                    rk += 1
                    msg = u"比赛结束~ 排名:%s" % rk
                    message = {"b":bid, "u":str(pre_player['uid']), "t":"game", "d":{"act":"match_over", "msg":msg}}
                    nsq_pub("response", message)
                logging.info(u"比赛结束:%s" % mid)
        


if __name__ == '__main__':
    print get_phone_model('Dalvik/2.1.0 (Linux; U; Android 5.1; vivo X6D Build/LMY47I)')

